package com.marvels.common.interceptor;

import com.dragon.web.commons.interceptor.LoginInterceptor;
import com.marvels.common.utils.MarvelsLogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.CorsRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义日志配置适配器
 * @author wangliang
 *
 */

@Configuration
public class MarvelsLogConfigurerAdapter extends WebMvcConfigurerAdapter {
	@Value("${platform.name.code}")
	private String basePath;
	
	@Autowired
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
	 
	/**
	 * 跨域配置
	 * filter拦截，在Interceptor之前执行
	 * @return
	 */
	@Bean
    public FilterRegistrationBean filterRegistrationBean() {
        // 对响应头进行CORS授权
		MarvelsCorsRegistration corsRegistration = new MarvelsCorsRegistration("/**");
        corsRegistration.allowedOrigins(CrossOrigin.DEFAULT_ORIGINS)
                .allowedMethods(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
                .allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS)
                /*.exposedHeaders(HttpHeaders.SET_COOKIE)*/
                .allowCredentials(false)
                .maxAge(CrossOrigin.DEFAULT_MAX_AGE);
        // 注册CORS过滤器
        UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
        configurationSource.registerCorsConfiguration("/**", corsRegistration.getCorsConfiguration());
        CorsFilter corsFilter = new CorsFilter(configurationSource);
        return new FilterRegistrationBean(corsFilter);
    }
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		MarvelsLogUtil.getInstance().info("======注册过滤器=====core-service basePath：" + basePath);
		//添加日志拦截器
		registry.addInterceptor(new MarvelsLogInterceptor()).addPathPatterns("/**").excludePathPatterns("/" + basePath + "/**");
		// IP拦截
		registry.addInterceptor(new MarvelsIPInterceptor()).addPathPatterns("/**").excludePathPatterns("/" + basePath + "/**");
		registry.addInterceptor(new MarvelsLoginInterceptor()).addPathPatterns("/**")
				.excludePathPatterns("/" + basePath + "/**")
				.excludePathPatterns("/approve/loanApplication/service/applyLoanUpload")
				.excludePathPatterns("/approve/**/api/**")
				.excludePathPatterns("/approve/loanApplication/service/loanOperation")
				.excludePathPatterns("/approve/loanList/service/downLoadBatch")
				.excludePathPatterns("/approve/loanList/service/downList")
				.excludePathPatterns("/approve/credit/report/service/downloadCreditExcel")
				.excludePathPatterns("/approve/credit/report/service/downloadacQuisitionExcel")
				.excludePathPatterns("/approve/credit/report/service/upload*")
				.excludePathPatterns("/approve/credit/intbank/service/loadAttachmentById/*")
				.excludePathPatterns("/approve/credit/**/service/down*/**")
				.excludePathPatterns("/system/service/api/v1/applyInfo")//jiayinjink
				.excludePathPatterns("/system/service/login")
				.excludePathPatterns("/financial/loan/**/service/down*")
				.excludePathPatterns("/financial/fund/**/service/down*")
				.excludePathPatterns("/financial/**/api/**/*")
				.excludePathPatterns("financial/**/api/**/*")
				.excludePathPatterns("/financial/**/api/*")
				.excludePathPatterns("/financial/loan/api/loanTrial")
				.excludePathPatterns("/financial/collection/**/service/down*")
				.excludePathPatterns("/financial/collection/**/service/upload*")
				.excludePathPatterns("/financial/loan/collectInfoProdide/service/**")
				.excludePathPatterns("/financial/loan/extensionFunction/service/**")
				.excludePathPatterns("/financial/collection/checkListQuery/service/downLoadUrgentExcel")
				.excludePathPatterns("/financial/checkBill/downLoadEverydayStatisticsExcel")
				
				
				.excludePathPatterns("/loanApply/api/**")
				.excludePathPatterns("/loanapply/basic_data/api/**")
				.excludePathPatterns("/loanApply/relationInfo/api/**")
				.excludePathPatterns("/loanApply/linkmanMobile/api/**")
				.excludePathPatterns("/loanApply/userBank/api/**")
				.excludePathPatterns("/loanApply/loan/api/**")
				.excludePathPatterns("/loanApply/channel/service/downloadUserChannelExcel")
				.excludePathPatterns("/loanApply/channel/service/downloadChannelRegisterUserExcel")
				.excludePathPatterns("/loanApply/customer/service/downloadCustomerListExcel")
				.excludePathPatterns("/loanApply/checkBill/downLoadFlowStatisticsExcel")
				.excludePathPatterns("/loanApply/checkBill/selectUserIdByName")
				.excludePathPatterns("/app/**/**")
		
				.excludePathPatterns("/product/param/api/**")
				.excludePathPatterns("/product/api/**")
				.excludePathPatterns("/product/param/customerType/service/selectTypeById")
				.excludePathPatterns("/product/param/customerType/service/selectAllType")
				.excludePathPatterns("/product/param/mngfee/service/selectByProductInfo")
				.excludePathPatterns("/product/param/consultingfee/service/selectByProductInfo")
				.excludePathPatterns("/product/mcpt/service/selectProductFundRelation")
				.excludePathPatterns("/product/param/consultingfee/service/selectByProductInfo")
				.excludePathPatterns("/product/param/mngfee/service/selectByProductInfo")
				.excludePathPatterns("/product/mcpt/service/queryOnlineProduct")
				.excludePathPatterns("/product/**/api/**")
				
				.excludePathPatterns("/system/**/freshAuthCash/**")
				.excludePathPatterns("/system/**/api/**")
				.excludePathPatterns("/financial/pay/api/hjPaymentNotify")
				.excludePathPatterns("/financial/pay/api/hjMerchantRechargeCallBack")
				.excludePathPatterns("/financial/pay/api/hjMerchantRechargeResult")
				.excludePathPatterns("/system/service/appRevealConfigure")
				.excludePathPatterns("/loanApply/checkBill/channelCostDownLoad")
				.addPathPatterns("/system/api/**");
		
		registry.addInterceptor(new MarvelsCommonInterceptor()).addPathPatterns("/**")
		.excludePathPatterns("/" + basePath + "/**")
		.excludePathPatterns("/approve/**/api/**")
		.excludePathPatterns("/financial/**/api/*")
		.excludePathPatterns("/loanApply/api/**")
		.excludePathPatterns("/loanApply/userBank/api/**")
		.excludePathPatterns("/loanApply/loan/api/**")
		.excludePathPatterns("/loanapply/basic_data/api/**")
		.excludePathPatterns("/loanApply/relationInfo/api/**")
		.excludePathPatterns("/loanApply/linkmanMobile/api/**")
		.excludePathPatterns("/product/param/api/**")
		.excludePathPatterns("/product/api/**")
		.excludePathPatterns("/product/**/api/**")
		.excludePathPatterns("/system/**/api/**")
		.excludePathPatterns("/system/service/currentUserMenuPath")
		.excludePathPatterns("/system/service/api/v1/applyInfo")//jiayinjink
		.excludePathPatterns("/system/service/login");
		
		// core-service 的拦截器
		registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/" + basePath + "/**")
		.excludePathPatterns("/" + basePath + "/attachment/**")
		.excludePathPatterns("/" + basePath + "/mrvel/**")
		.excludePathPatterns("/" + basePath + "/callBack/**")
		.excludePathPatterns("/" + basePath + "/pay/callback/**")
		.excludePathPatterns("/" + basePath + "/equipment/**")
		.excludePathPatterns("/" + basePath + "/loan/queryProductType")
		.excludePathPatterns("/" + basePath + "/loanSuccessList")
		.excludePathPatterns("/" + basePath + "/sdk/**")
		.excludePathPatterns("/" + basePath + "/upload/**")
		.excludePathPatterns("/" + basePath + "/question/**")
		.excludePathPatterns("/" + basePath + "/msg/verify/pictureVerify")
		.excludePathPatterns("/" + basePath + "/msg/get/pictureVerify")
		.excludePathPatterns("/" + basePath + "/file/upload/**")
		.excludePathPatterns("/" + basePath + "/tongdun/**")
		.excludePathPatterns("/" + basePath + "/clientUser/**")
		.excludePathPatterns("/" + basePath + "/faceSign/**")
		.excludePathPatterns("/" + basePath + "/yzy/**")
		.excludePathPatterns("/" + basePath + "/sms/ykd/register")
		.excludePathPatterns("/" + basePath + "/msg/verify/pictureVerify")
		.excludePathPatterns("/" + basePath + "/msg/get/pictureVerify")
		.excludePathPatterns("/" + basePath + "/moxie/call/**")
		.excludePathPatterns("/" + basePath + "/sms/ykd/**")
		.excludePathPatterns("/" + basePath + "/wheTherDownLoad/**")
		.excludePathPatterns("/" + basePath + "/app/config/**");
		super.addInterceptors(registry);
	}
	
	
	
	@Bean
    public ReturnHandler getReturnHandler(){
        List<HttpMessageConverter<?>> messageConverters = requestMappingHandlerAdapter.getMessageConverters();
        return new ReturnHandler(messageConverters);//初始化过滤器
    }
 
 
    /**
     * 解决ReturnHandler不生效问题
     */
    @PostConstruct
    public void init() {
        final List<HandlerMethodReturnValueHandler> originalHandlers = new ArrayList<>(
                requestMappingHandlerAdapter.getReturnValueHandlers());
        final int deferredPos = obtainValueHandlerPosition(originalHandlers, HttpEntityMethodProcessor.class);
        originalHandlers.add(deferredPos - 1, getReturnHandler());
        requestMappingHandlerAdapter.setReturnValueHandlers(originalHandlers);
        return;
    }
 
    private int obtainValueHandlerPosition(final List<HandlerMethodReturnValueHandler> originalHandlers, Class<?> handlerClass) {
        for (int i = 0; i < originalHandlers.size(); i++) {
            final HandlerMethodReturnValueHandler valueHandler = originalHandlers.get(i);
            if (handlerClass.isAssignableFrom(valueHandler.getClass())) {
                return i;
            }
        }
        return -1;
    }
}

class MarvelsCorsRegistration extends CorsRegistration {

    public MarvelsCorsRegistration(String pathPattern) {
        super(pathPattern);
    }

    @Override
    public CorsConfiguration getCorsConfiguration() {
        return super.getCorsConfiguration();
    }
}
